package com.biomatch.mqtt;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
@Component
public class MqttClient {
    MqttClientConfig mqttClientConfig;
    org.eclipse.paho.client.mqttv3.MqttClient client;

    public void setMqttClientConfig(MqttClientConfig mqttClientConfig) {
        this.mqttClientConfig = mqttClientConfig;
    }

    public void init(){
        if(this.mqttClientConfig != null && !this.isConnected()){
            try{
                this.client = new org.eclipse.paho.client.mqttv3.MqttClient(mqttClientConfig.getBroker(), mqttClientConfig.getClientId(), new MemoryPersistence());
                MqttConnectOptions options = new MqttConnectOptions();
                options.setCleanSession(new Boolean(mqttClientConfig.getCleansession()));
                options.setKeepAliveInterval(mqttClientConfig.getKeepAliveInterval());
                options.setUserName(mqttClientConfig.getUserName());
                options.setPassword(mqttClientConfig.getPassword().toCharArray());
                this.client.connect(options);
                this.client.subscribe("/lock/#");
                this.client.setCallback(new MqttClientCallBack());
                log.info("mqttclient "+mqttClientConfig.getClientId()+" connect successful!");
            }catch (Exception ex){
                ex.printStackTrace();
                reconnect();
            }

        }
    }

    public void reconnect() {
        while (!this.isConnected()){
            try{
                log.info("mqttclient "+mqttClientConfig.getClientId()+" reconnecting ...");
                this.init();
            }catch(Exception e){
                this.disconnected();
            }
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public boolean isConnected(){
        if(this.client != null && this.client.isConnected()){
            return true;
        }
        return  false;
    }

    public void disconnected(){
        if(isConnected()){
            try{
                this.client.unsubscribe("/lock/#");
                this.client.disconnect();
                this.client.close();
            }catch (MqttException ex){
                ex.printStackTrace();
            }
        }
        this.client = null;
    }
    public void subscribe(String topic, MqttCallback mqttCallback) {
        if(this.isConnected()){
            try {
                this.client.subscribe(topic);
                this.client.setCallback(mqttCallback);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }

    public void publish(String topic,String message){
        if(this.isConnected()){
            try{
                this.client.publish(topic,new MqttMessage(message.getBytes()));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    };

    public void unSubscribe(String topic){
        if(isConnected()){
            try {
                this.client.unsubscribe(topic);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }
}
